package net.csdn.business.common.feign.interceptor;

import io.opentracing.Scope;
import io.opentracing.Span;
import io.opentracing.Tracer;
import io.opentracing.propagation.Format;
import io.opentracing.tag.Tags;
import io.opentracing.util.GlobalTracer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.util.Set;

/**
 * @ClassName SysLogTraceHeader
 * @Description 在请求的服务间增加trace相关的header
 * @Author zhangyl
 * @Date 2023/4/19 11:28
 */
@Slf4j
@RequiredArgsConstructor
public class SysLogTraceHeaderInterceptor implements Interceptor {

    private final Tracer tracer;

    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Response resopnse=null;
        Request oldRequest = chain.request(); // 获取旧连接
        Request.Builder requestBuilder = oldRequest.newBuilder(); // 建立新的构建者
        // 将旧请求的请求方法和请求体设置到新请求中
        requestBuilder.method(oldRequest.method(), oldRequest.body());
        // 获取旧请求的头
        Headers headers = oldRequest.headers();
        if(headers!=null) {
            Set<String> names = headers.names();
            for (String name : names) {
                String value = headers.get(name);
                // 将旧请求的头设置到新请求中
                requestBuilder.header(name, value);
            }
        }
        Span span =null;
        Scope scope =null;
        if(tracer!=null){
            // 为当前 RestTemplate 调用，创建一个 Span
            span = GlobalTracer.get().activeSpan();
            if(span==null){
                span = tracer.buildSpan("feign-rpc")
                        .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
                        .withTag("feign-rpc-url", oldRequest.url().toString())
                        .start();
                scope =this.tracer.activateSpan(span);
            }
            // 将当前 SpanContext 注入到 HttpHeaders
            tracer.inject(span.context(), Format.Builtin.HTTP_HEADERS,
                    new HttpHeadersCarrier(requestBuilder));
        }
        // 建立新请求连接
        Request newRequest = requestBuilder.build();
        String traceInfo=newRequest.header("uber-trace-id");
        log.info("----feign remote request tarceInfo:{}----",traceInfo);
        try{
            resopnse=chain.proceed(newRequest);
        } catch (Exception ex) {
            throw ex;
        } finally {
            if(scope!=null){
                scope.close();
            }
            if(span!=null){
                span.finish();
            }
        }
        return resopnse;
    }
}
